package io.renren.sf.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.*;
import io.renren.sf.dao.CbStiffBookDao;
import io.renren.sf.entity.*;
import io.renren.sf.feign.OssFeign;
import io.renren.sf.service.*;
import io.renren.sf.vo.BookEditionInfoVo;
import io.renren.sf.vo.StiffButtonVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;


@Service("cbStiffBookService")
public class CbStiffBookServiceImpl extends ServiceImpl<CbStiffBookDao, CbStiffBookEntity> implements CbStiffBookService {
    @Autowired
    private CbStiffUnitService cbStiffUnitService;

    @Autowired
    private CbStiffChapterService cbStiffChapterService;

    @Autowired
    private CbStiffTypefaceService stiffTypefaceService;

    @Autowired
    private CbStiffReadingService stiffReadingService;

    @Autowired
    private CbStiffQuickspotService stiffQuickspotService;

    @Autowired
    private CbStiffCalligraphyService stiffCalligraphyService;

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    private OssFeign ossFeign;
    private File dir;

    @Override
    public Page<CbStiffBookEntity> getBookBySystemId(Map<String, Object> params) {
        String systemId = (String) params.get("systemId");
        long page = Long.parseLong((String) params.get("page"));
        long limit = Long.parseLong((String) params.get("limit"));
        QueryWrapper<CbStiffBookEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(systemId)) {
            queryWrapper.eq("sid", systemId);
        }
        Page<CbStiffBookEntity> bookPage = new Page<CbStiffBookEntity>(page, limit);
        baseMapper.selectPage(bookPage, queryWrapper);
        return bookPage;
    }

    @Override
    public synchronized String createZip(long bid) throws Exception {
        // 将Long转化成String
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        List<CompletableFuture<String>> listFuture = new ArrayList<>();
        CompletableFuture<String> future1 = null,future2 = null,future3 = null,future4 = null,future5 = null,future6 = null,future7 = null,future8 = null,future9 = null,future10 = null;

        //1.获取目录
        future1 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffUnitEntity> units = cbStiffUnitService.list(new QueryWrapper<CbStiffUnitEntity>().eq("bid", bid).orderByAsc("uorder"));
            // 没有就直接return ""
            if (CollectionUtils.isEmpty(units)) {
                return "该书存在目录信息未添加";
            }
            for (CbStiffUnitEntity unit : units) {
                List<CbStiffChapterEntity> chapters = cbStiffChapterService.list(new QueryWrapper<CbStiffChapterEntity>().eq("uid", unit.getId()));
                for (CbStiffChapterEntity chapter : chapters) {
                    String suffix = "";
                    String md5 = "";
                    // 下载教案课件
                    String url = chapter.getCourseBook();
                    if (!StringUtils.isEmpty(url)) {
                        suffix = url.substring(url.lastIndexOf("."), url.length());
                        md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                        //return "该书存在章节的教案课件未添加";
                    }

                    // 教案课件音频
                    url = chapter.getCourseBookAudio();
                    if (!StringUtils.isEmpty(url)) {
                        suffix = url.substring(url.lastIndexOf("."), url.length());
                        md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                        //return "该书存在章节教案课件音频未添加";
                    }
                }
                unit.setChapters(chapters);
            }
            // 1.2生成目录json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(units), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.CONTENT.getName());
            return "";
        }, executor);

        //2.每章节内容
        future2 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffChapterPictureEntity> chapterpics = this.baseMapper.getchappics(bid);
            // 2.1生成章节内容json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(chapterpics), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.ZJNR.getName());
            //下载图片章节图片
            for (CbStiffChapterPictureEntity chapterpic : chapterpics) {
                String suffix = "";
                String md5 = "";
                String url = chapterpic.getChapterPicture();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在章节图片未添加";
                }
            }
            return "";
        }, executor);

        //3.获取生字学习
        future3 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffTypefaceEntity> typefaces = this.baseMapper.gettypefaces(bid);
            // 生成生字学习json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(typefaces), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.SZXX.getName());
            //下载生字图片、粉笔视频、钢笔视频、识字视频
            for (CbStiffTypefaceEntity typeface : typefaces) {
                String suffix = "";
                String md5 = "";
                //生字图片
                String url = typeface.getTypeface();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在章节图片未添加";
                }
            }
            return "";
        }, executor);

        //4.认读
        future4 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffReadingEntity> readings = this.baseMapper.getreadings(bid);
            // 生成认读json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(readings), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.RD.getName());
            //下载语音、认读动图、视频
            for (CbStiffReadingEntity reading : readings) {
                String suffix = "";
                String md5 = "";
                //语音
                String url = reading.getVoice();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在认读语音未添加";
                }
                //认读动图
                url = reading.getMovingPicture();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在认读动图未添加";
                }
                //视频
                url = reading.getVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在认读视频未添加";
                }
            }
            return "";
        }, executor);

        //5.找茬
        future5 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffQuickspotEntity> quickspots = this.baseMapper.getquickspots(bid);
            // 生成找茬json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(quickspots), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.ZC.getName());
            //下载找茬
            for (CbStiffQuickspotEntity quickspot : quickspots) {
                String suffix = "";
                String md5 = "";
                //找茬
                String url = quickspot.getQuickspotPicture();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在找茬图片未添加";
                }
            }
            return "";
        }, executor);

        //6.书法基础
        future6 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffCalligraphyEntity> calligraphys = stiffCalligraphyService.list();
            for (CbStiffCalligraphyEntity calligraphy : calligraphys) {
                for (int i = 1; i <= 3; ++i) {
                    List<CbStiffCalligraphyPictureEntity> calligraphyPictures = this.baseMapper.getCalligraphyPictures(i);
                    //下载书法基础图片、扩展图片、扩展视频
                    for (CbStiffCalligraphyPictureEntity calligraphyPicture : calligraphyPictures) {
                        String suffix = "";
                        String md5 = "";
                        //书法基础图片
                        String url = calligraphyPicture.getCalligraphyPicture();
                        if (!StringUtils.isEmpty(url)) {
                            suffix = url.substring(url.lastIndexOf("."), url.length());
                            md5 = MD5.encrypt(url) + suffix;
                            Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                            //return "该书存在书法基础图片未添加";
                        }
                        //扩展图片
                        url = calligraphyPicture.getCalligraphyPicture();
                        if (!StringUtils.isEmpty(url)) {
                            suffix = url.substring(url.lastIndexOf("."), url.length());
                            md5 = MD5.encrypt(url) + suffix;
                            Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                            //return "该书存在书法基础扩展图片未添加";
                        }
                        //扩展视频
                        url = calligraphyPicture.getCalligraphyPicture();
                        if (!StringUtils.isEmpty(url)) {
                            suffix = url.substring(url.lastIndexOf("."), url.length());
                            md5 = MD5.encrypt(url) + suffix;
                            Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                            //return "该书存在书法基础扩展视频未添加";
                        }
                    }
                    calligraphy.setCalligraphyPictures(calligraphyPictures);
                }
            }
            // 生成书法基础json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(calligraphys), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.SFJC.getName());
            return "";
        }, executor);

        //7.粉笔视频
        future7 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffChalkVideoEntity> chalkVideos = this.baseMapper.getchalkvideos(bid);
            // 生成粉笔视频json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(chalkVideos), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.FBSP.getName());
            //下载粉笔视频
            for (CbStiffChalkVideoEntity chalkVideo : chalkVideos) {
                String suffix = "";
                String md5 = "";
                //粉笔视频、bgm、解析音频
                String url = chalkVideo.getChalkVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在粉笔视频未添加";
                }

                url = chalkVideo.getChalkVideoBgm();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在粉笔视频bgm未添加";
                }

                url = chalkVideo.getChalkVideoDescriptionVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在粉笔视频解析音频未添加";
                }
            }
            return "";
        }, executor);

        //8.钢笔视频
        future8 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffPenVideoEntity> penVideos = this.baseMapper.getpenvideos(bid);
            // 生成生字学习json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(penVideos), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.GBSP.getName());
            //下载钢笔视频
            for (CbStiffPenVideoEntity penVideo : penVideos) {
                String suffix = "";
                String md5 = "";
                //钢笔视频、bgm、解析音频
                String url = penVideo.getPenVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在钢笔视频未添加";
                }

                url = penVideo.getPenVideoBgm();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在钢笔视频bgm未添加";
                }

                url = penVideo.getPenVideoDescriptionVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在钢笔视频解析音频未添加";
                }
            }
            return "";
        }, executor);

        //9.识字视频
        future9 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffLiteracyVideoEntity> literacyVideos = this.baseMapper.getliteracyvideos(bid);
            // 生成识字视频json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(literacyVideos), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.SZSP.getName());
            //下载识字视频、bgm、解析音频
            for (CbStiffLiteracyVideoEntity literacyVideo : literacyVideos) {
                String suffix = "";
                String md5 = "";
                //识字视频、bgm、解析音频
                String url = literacyVideo.getLiteracyVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在识字视频未添加";
                }

                url = literacyVideo.getLiteracyVideoBgm();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在识字视频bgm未添加";
                }

                url = literacyVideo.getLiteracyVideoDescriptionVideo();
                if (!StringUtils.isEmpty(url)) {
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.ZipStiff.PATH.getName());
                    //return "该书存在识字视频解析音频未添加";
                }
            }
            return "";
        }, executor);

        //10.获取六步按钮
        future10 = CompletableFuture.supplyAsync(() -> {
            List<CbStiffTypefaceEntity> typefaces = this.baseMapper.gettypefaces(bid);
            List<StiffButtonVo> stiffButtonVoList = new ArrayList<>();
            //获取所有生字的六步按钮
            for (CbStiffTypefaceEntity typeface : typefaces) {
                List<String> buttonList = new ArrayList<>();
                List<CbStiffReadingEntity> readings = stiffReadingService.list(new QueryWrapper<CbStiffReadingEntity>().eq("tid", typeface.getId()));
                if (readings.size() > 0)    buttonList.add("认读");
                if (typeface.getChalkVideo() != null && !typeface.getChalkVideo().equals("") && typeface.getChalkVideoDescription() != null && !typeface.getChalkVideoDescription().equals("")) {
                    buttonList.add("粉笔视频");
                }
                if (typeface.getPenVideo() != null && !typeface.getPenVideo().equals("") && typeface.getPenVideoDescription() != null && !typeface.getPenVideoDescription().equals("")) {
                    buttonList.add("钢笔视频");
                }
                List<CbStiffQuickspotEntity> quickspots = stiffQuickspotService.list(new QueryWrapper<CbStiffQuickspotEntity>().eq("tid", typeface.getId()));
                if (quickspots != null && quickspots.size() == 4) buttonList.add("一起来找茬");
                if (typeface.getLiteracyVideo() != null && !typeface.getLiteracyVideo().equals("")) buttonList.add("识字视频");
                List<CbStiffCalligraphyEntity> stiffCalligraphys = stiffCalligraphyService.list(new QueryWrapper<CbStiffCalligraphyEntity>().eq("tid", typeface.getId()));
                if (stiffCalligraphys != null) buttonList.add("书法基础");

                StiffButtonVo stiffButtonVo = new StiffButtonVo();
                stiffButtonVo.setButtonList(buttonList);
                stiffButtonVo.setId(typeface.getId());
                stiffButtonVoList.add(stiffButtonVo);
            }
            // 生成识字视频json
            Download.createJsonFile(JSON.toJSONString(ResponseData.success(stiffButtonVoList), serializeConfig), Constant.ZipStiff.PATH.getName(), Constant.ZipStiff.LBAN.getName());
            return "";
        }, executor);

        listFuture.add(future1);
        listFuture.add(future2);
        listFuture.add(future3);
        listFuture.add(future4);
        listFuture.add(future5);
        listFuture.add(future6);
        listFuture.add(future7);
        listFuture.add(future8);
        listFuture.add(future9);
        listFuture.add(future10);
        CompletableFuture.allOf(listFuture.toArray(new CompletableFuture[]{})).get();

        // ===
        for(CompletableFuture<String> future:listFuture)
            if(!StringUtils.isEmpty(future.get()))
                return future.get();

        // 将D:\\hanzhiZipStiff\\下的文件打成压缩包
        // 得到file数组
        File[] files = getFiles(Constant.ZipStiff.PATH.getName());
        String zipPath = Constant.Zip.YSB.getName() + bid + ".zip";
        File zipFile = new File(zipPath); // zip存放路径
        ZipMultiFile.zipFiles(files, zipFile);
        R upload = ossFeign.uploadZip(zipPath);// 上传至oss
        return (String) upload.get("url");
    }

    @Override
    public List<BookEditionInfoVo> getAllBookEditionInfoVo() {
        return this.baseMapper.getAllBookEditionInfoVo();
    }

    private File[] getFiles(String path) {
        File dir = new File(path);
        return dir.listFiles();
    }
}
